import mongoose, { Schema, Document } from 'mongoose';

/**
 * 角色接口定义
 */
export interface IRole extends Document {
  name: string;
  slug: string;
  description?: string;
  organization?: mongoose.Types.ObjectId; // 组织级角色
  scope: 'system' | 'organization' | 'team'; // 角色范围
  permissions: mongoose.Types.ObjectId[]; // 权限列表
  isSystem: boolean; // 是否是系统预定义角色
  isDefault: boolean; // 是否是默认角色（新用户自动分配）
  priority: number; // 优先级，用于角色冲突解决
  metadata?: {
    color?: string;
    icon?: string;
  };
  createdAt: Date;
  updatedAt: Date;
}

/**
 * 角色 Schema
 */
const RoleSchema = new Schema<IRole>(
  {
    name: {
      type: String,
      required: [true, 'Role name is required'],
      trim: true,
      minlength: [2, 'Role name must be at least 2 characters'],
      maxlength: [50, 'Role name cannot exceed 50 characters']
    },
    slug: {
      type: String,
      required: true,
      lowercase: true,
      trim: true,
      match: [/^[a-z0-9_-]+$/, 'Slug can only contain lowercase letters, numbers, underscores and hyphens']
    },
    description: {
      type: String,
      maxlength: [200, 'Description cannot exceed 200 characters']
    },
    organization: {
      type: Schema.Types.ObjectId,
      ref: 'Organization',
      default: null
    },
    scope: {
      type: String,
      required: true,
      enum: ['system', 'organization', 'team'],
      default: 'organization'
    },
    permissions: [{
      type: Schema.Types.ObjectId,
      ref: 'Permission'
    }],
    isSystem: {
      type: Boolean,
      default: false
    },
    isDefault: {
      type: Boolean,
      default: false
    },
    priority: {
      type: Number,
      default: 0,
      min: 0,
      max: 100
    },
    metadata: {
      color: {
        type: String,
        match: [/^#[0-9A-F]{6}$/i, 'Color must be a valid hex color']
      },
      icon: String
    }
  },
  {
    timestamps: true,
    toJSON: { virtuals: true },
    toObject: { virtuals: true }
  }
);

// 复合索引
RoleSchema.index({ slug: 1, organization: 1 }, { unique: true });
RoleSchema.index({ scope: 1 });
RoleSchema.index({ isSystem: 1 });
RoleSchema.index({ organization: 1, isDefault: 1 });

// 虚拟字段：权限数量
RoleSchema.virtual('permissionCount').get(function(this: IRole) {
  return this.permissions.length;
});

// 实例方法：检查是否有某个权限
RoleSchema.methods.hasPermission = function(permissionId: string): boolean {
  return this.permissions.some(id => id.toString() === permissionId.toString());
};

// 实例方法：添加权限
RoleSchema.methods.addPermission = function(permissionId: mongoose.Types.ObjectId) {
  if (!this.hasPermission(permissionId.toString())) {
    this.permissions.push(permissionId);
  }
};

// 实例方法：移除权限
RoleSchema.methods.removePermission = function(permissionId: string) {
  this.permissions = this.permissions.filter(id => id.toString() !== permissionId.toString());
};

// 静态方法：初始化系统角色
RoleSchema.statics.initializeSystemRoles = async function() {
  const Permission = mongoose.model('Permission');

  // 获取所有权限
  const allPermissions = await Permission.find({});
  const permissionMap = new Map(allPermissions.map(p => [p.name, p._id]));

  const systemRoles = [
    {
      name: 'Super Admin',
      slug: 'super_admin',
      description: '超级管理员，拥有所有权限',
      scope: 'system',
      isSystem: true,
      isDefault: false,
      priority: 100,
      permissions: allPermissions.map(p => p._id),
      metadata: { color: '#FF4D4F', icon: 'crown' }
    },
    {
      name: 'Organization Owner',
      slug: 'org_owner',
      description: '组织所有者，管理组织的所有资源',
      scope: 'organization',
      isSystem: true,
      isDefault: false,
      priority: 90,
      permissions: allPermissions
        .filter(p => !p.isSystem || p.category !== 'system')
        .map(p => p._id),
      metadata: { color: '#722ED1', icon: 'user-check' }
    },
    {
      name: 'Organization Admin',
      slug: 'org_admin',
      description: '组织管理员，管理用户和团队',
      scope: 'organization',
      isSystem: true,
      isDefault: false,
      priority: 80,
      permissions: allPermissions
        .filter(p =>
          ['users:read', 'users:create', 'users:update', 'teams:read', 'teams:create',
           'teams:update', 'teams:manage', 'roles:read', 'roles:assign'].includes(p.name)
        )
        .map(p => p._id),
      metadata: { color: '#1890FF', icon: 'setting' }
    },
    {
      name: 'Engineer',
      slug: 'engineer',
      description: '运维工程师，处理告警和工单',
      scope: 'organization',
      isSystem: true,
      isDefault: true,
      priority: 50,
      permissions: allPermissions
        .filter(p =>
          ['alerts:read', 'alerts:update', 'tickets:read', 'tickets:create', 'tickets:update',
           'tickets:assign', 'knowledge:read', 'knowledge:create', 'analytics:read'].includes(p.name)
        )
        .map(p => p._id),
      metadata: { color: '#52C41A', icon: 'tool' }
    },
    {
      name: 'Developer',
      slug: 'developer',
      description: '开发人员，查看监控和告警',
      scope: 'organization',
      isSystem: true,
      isDefault: false,
      priority: 40,
      permissions: allPermissions
        .filter(p =>
          ['alerts:read', 'tickets:read', 'tickets:create', 'knowledge:read',
           'analytics:read'].includes(p.name)
        )
        .map(p => p._id),
      metadata: { color: '#13C2C2', icon: 'code' }
    },
    {
      name: 'Viewer',
      slug: 'viewer',
      description: '查看者，只读权限',
      scope: 'organization',
      isSystem: true,
      isDefault: false,
      priority: 10,
      permissions: allPermissions
        .filter(p => p.action === 'read')
        .map(p => p._id),
      metadata: { color: '#8C8C8C', icon: 'eye' }
    },
    {
      name: 'Team Leader',
      slug: 'team_leader',
      description: '团队负责人，管理团队和分配任务',
      scope: 'team',
      isSystem: true,
      isDefault: false,
      priority: 60,
      permissions: allPermissions
        .filter(p =>
          ['teams:read', 'teams:update', 'teams:manage', 'tickets:read', 'tickets:create',
           'tickets:update', 'tickets:assign', 'alerts:read', 'alerts:update'].includes(p.name)
        )
        .map(p => p._id),
      metadata: { color: '#FA8C16', icon: 'team' }
    }
  ];

  for (const role of systemRoles) {
    await this.findOneAndUpdate(
      { slug: role.slug, organization: null },
      role,
      { upsert: true, new: true }
    );
  }
};

// 静态方法：查找组织的所有角色
RoleSchema.statics.findByOrganization = function(organizationId: string) {
  return this.find({
    $or: [
      { organization: organizationId },
      { organization: null, scope: { $in: ['system', 'organization'] } }
    ]
  })
    .populate('permissions')
    .sort({ priority: -1, name: 1 });
};

// 静态方法：获取默认角色
RoleSchema.statics.getDefaultRole = function(organizationId?: string) {
  const query: any = { isDefault: true };

  if (organizationId) {
    query.$or = [
      { organization: organizationId },
      { organization: null }
    ];
  } else {
    query.organization = null;
  }

  return this.findOne(query).sort({ priority: -1 });
};

const Role = mongoose.model<IRole>('Role', RoleSchema);

export default Role;
